﻿using Autofac.Core;
using Essensoft.AspNetCore.Payment.WeChatPay;
using Essensoft.AspNetCore.Payment.WeChatPay.V2.Notify;
using Essensoft.AspNetCore.Payment.WeChatPay.V2;
using JindaTech.Application.Business.YwActivePayApp.Dto;
using JindaTech.Application.Login;
using JindaTech.Common.Utility;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.IO;
using System;
using System.Threading.Tasks;
using JindaTech.Common.Extensions;
using static JindaTech.Api.Controllers.Tx.WxOffiAccountController;
using JindaTech.Application.Business.YwActiveClassCourseApp.Dto;
using JindaTech.Application.Business.YwActiveClassCourseApp.Service;
using JindaTech.Application.Business.YwActiveApp.Service;
using JindaTech.Application.Business.YwActivePayApp.Service;
using Essensoft.AspNetCore.Payment.WeChatPay.V2.Request;
using System.Threading;
using FastReport.AdvMatrix;
using JindaTech.Common.NLog;
using NLog;
using Newtonsoft.Json;
using static System.Runtime.InteropServices.JavaScript.JSType;
using JindaTech.Common.Filtes;
using System.ComponentModel.DataAnnotations;

namespace JindaTech.Api.Controllers.Icbc
{
    [ApiController]
    [Route("icbc")]
    public class IcbcController : Controller
    {
        private readonly IcbcTool _icbcTool;
        private readonly IYwActivePayAppService _payService;
        private readonly IYwActiveService _activeService;
        private readonly IYwActiveClassCourseAppService _ywActiveClassCourseAppService;

        public IcbcController(IWebHostEnvironment hostingEnvironment, IOptions<WeChatPayOptions> optionsAccessor
            , IYwActivePayAppService payService, IYwActiveService activeService
            , IYwActiveClassCourseAppService ywActiveClassCourseAppService)
        {
            _payService = payService;
            _activeService = activeService;
            _ywActiveClassCourseAppService = ywActiveClassCourseAppService;

            _icbcTool = new IcbcTool(hostingEnvironment, optionsAccessor);
        }

        [HttpPost, Route("showpay"), AllowAnonymous]
        public async Task<IActionResult> Showpay(WeChatPayPubPayViewModel viewModel)
        {
            WebResponseContent webResponse = new WebResponseContent();


            YwActiveClassCourseIdDto ywActiveClassCourseId = new YwActiveClassCourseIdDto() { F_Id = viewModel.F_ActiveCourseId };
            var course = _ywActiveClassCourseAppService.GetEntity(ywActiveClassCourseId);
            if (!course.F_StartPay.GetValueOrDefault())
            {
                webResponse.Error("该活动未开始付款");
                return Json(webResponse);
            }
            //F_Account单位元，TotalFee单位分
            if (course.F_Account.GetValueOrDefault() * 100 != viewModel.TotalFee)
            {
                webResponse.Error(viewModel.OutTradeNo + "订单付款金额不正确");
                return Json(webResponse);
            }

            YwActivePayBillNoDto paydto = new YwActivePayBillNoDto() { F_BillNo = viewModel.OutTradeNo };
            var pay = _payService.GetYwActivePay(paydto);
            if (pay != null)
            {
                if (pay.F_IsPay.GetValueOrDefault())
                {
                    webResponse.Error(viewModel.OutTradeNo + "订单已付款");
                    return Json(webResponse);
                }
            }

            var host = HttpContext.GetLocalHost();
            var notifyUrl = host + "icbc/notify";
            string html = _icbcTool.Showpay(notifyUrl, viewModel.OutTradeNo, viewModel.TotalFee.ToString(), viewModel.OpenId, viewModel.Body);

            var data = new
            {
                Html = html
            };

            //写paylog
            YwActivePayDto log = new YwActivePayDto();
            log.F_ActiveId = viewModel.F_ActiveId;
            log.F_CourseId = viewModel.F_ActiveCourseId;
            log.F_BillNo = viewModel.OutTradeNo;
            log.F_PayOrReturn = 0;
            log.F_Account = viewModel.TotalFee;
            log.F_IsPay = false;
            log.F_Notes = viewModel.Body;
            log.F_CreaTeDate = DateTime.Now;
            log.F_CreateUser = UserContext.Current.UserId;
            _payService.AddEntity(log);

            LoopQuery(viewModel.OutTradeNo);


            webResponse.OK(data);
            return Json(webResponse);
        }

        [HttpPost, Route("orderQry"), AllowAnonymous]
        public async Task<IActionResult> OrderQry(OrderQryViewModel viewModel)
        {
            try
            {
                _icbcTool.orderqry(viewModel.OutTradeNo);
            }
            catch { }
            WebResponseContent webResponse = new WebResponseContent();
            webResponse.OK();
            return Json(webResponse);

        }

        /// <summary>
        /// 循环查询订单状态
        /// </summary>
        /// <param name="orderno"></param>
        private void LoopQuery(string orderno)
        {
            var task = Task.Run(() =>
            {
                Thread.Sleep(1000 * 30);//30秒后开始查询
                int count = 0;//最多查询30次
                while (true)
                {
                    count++;

                    try
                    {
                        var icbcResponse = _icbcTool.orderqry(orderno);
                        if (icbcResponse.getReturnCode() == 0)
                        {
                            //此写付款成功后的业务代码
                            YwActivePayDto dto = new YwActivePayDto();
                            dto.F_PayOrReturn = 0;
                            dto.F_BillNo = icbcResponse.getOutTradeNo();
                            dto.F_OutOrderNo = icbcResponse.getOrderId();
                            _payService.PayCallBackUpd(dto);

                            break;
                        }
                        else
                        {
                            string errorMsg = icbcResponse.getReturnCode() + ":" + icbcResponse.getReturnMsg() + "-->" + JsonConvert.SerializeObject(icbcResponse);
                            NLogUtil.WriteDBLog(LogLevel.Error, errorMsg);
                        }
                    }
                    catch (Exception e)
                    {
                        NLogUtil.WriteDBLog(LogLevel.Error, e.Message, e);
                    }

                    if (count > 30)
                        break;
                }
                Thread.Sleep(1000 * 60);//1分钟查一次

            });
        }

    }

    public class OrderQryViewModel
    {
        [Required]
        [Display(Name = "out_trade_no")]
        [JsonConverter(typeof(AntiXssNewtonsoftConverter))]
        public string OutTradeNo { get; set; }
    }
}
